﻿using System;
using System.Text;
using RAP.Framework.Libary.DomTemplateBuilder.Element.Conditional;
using RAP.Framework.Libary.DomTemplateBuilder.Interface;
using System.Collections;
using RAP.Framework.Libary.Utils;
using RAP.Framework.Libary.DomTemplateBuilder.Element;

namespace RAP.Framework.Libary.DomTemplateBuilder.Handler.Conditional
{
	/// <summary>
	/// 比较类型的Handler基类
	/// </summary>
	public abstract class CompareHandler : ConditionalHandler
    {
        public virtual new CompareBase Element
        {
            get
            {
                return base.Element as CompareBase;
            }
            set
            {
                base.Element = value as ConditionalBase;
            }
        }
		
        /// <summary>
        /// 获取属性名称
        /// </summary>
        /// <returns></returns>
        public virtual string CompareProperty
        {
            get
            {
                return this.Element.CompareProperty;
            }
        }

        /// <summary>
        /// 根据ComparePropertyValueType获取当前Handler的CompareProperty的ParamObject对象
        /// </summary>
        /// <param name="rootParamObject"></param>
        /// <param name="parentParamObject"></param>
        /// <param name="context"></param>
        protected virtual object GetCompareParamObject ( object rootParamObject, object parentParamObject, ITemplateRenderContext context )
        {
            var compareParamObject = parentParamObject;
			var ele = this.Element;
            switch ( ele.CompareValueStyle )
            {
                case PropertyValueStyles.RootObject:
                    compareParamObject = rootParamObject;
                    break;

                case PropertyValueStyles.Context:
                    compareParamObject = context;
                    break;

                case PropertyValueStyles.NotSet:
                case PropertyValueStyles.Parent:
                    compareParamObject = parentParamObject;
                    break;
            }
            return compareParamObject;
        }

        /// <summary>
        /// 获取被比较的属性值
        /// </summary>
        /// <param name="rootParamObject"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public virtual object GetCompareValue ( object rootParamObject, object parentParamObject, ITemplateRenderContext context )
        {
			if ( !this.CompareProperty.IsNullOrEmpty ( ) )
            {
				var compareParamObject = this.GetCompareParamObject ( rootParamObject, parentParamObject, context );
                if ( compareParamObject != null )
                {
					var compareProperty = this.GetPropertyName ( this.CompareProperty, rootParamObject, parentParamObject, context );
					return this.GetExpressionValue ( compareParamObject, compareProperty, rootParamObject, parentParamObject, context );
                }
            }
            return this.Element.CompareValue;
        }


        public override void DoRender ( StringBuilder writer, object rootParamObject, object parentParamObject, ITemplateRenderContext context )
        {
			var paramObject = this.GetParamObject ( rootParamObject, parentParamObject, context );
            this.GetCompareParamObject ( rootParamObject, parentParamObject, context );
            if ( this.IsCondition ( rootParamObject, parentParamObject, context ) )
            {
                base.DoRenderChildNodes ( writer, rootParamObject, paramObject, context );
            }
            else
            {
				var elseHandler = this.ElseHandler;
                if ( elseHandler != null )
                {
                    elseHandler.DoRender ( writer, rootParamObject, paramObject, context );
                }
            }
        }

		protected virtual IList GetCompareValues ( object rootParamObject, object parentParamObject, ITemplateRenderContext context )
		{
			var compareValue = this.GetCompareValue ( rootParamObject, parentParamObject, context );
			IList compareValues = null;
			if ( compareValue is string )
			{
				compareValues = ( compareValue as string ).Split ( Consts.STRING_SPLIT_CHAR, StringSplitOptions.None );
			}
			else if ( compareValue is IList )
			{
				compareValues = compareValue as IList;
			}
			else
			{
				compareValues = new ArrayList ( ) { compareValue };
			}
			return compareValues;
		}

		protected override bool DoCompareValue ( object propertyValue, object rootParamObject, object parentParamObject, ITemplateRenderContext context )
		{
			var compareValues = this.GetCompareValues ( rootParamObject, parentParamObject, context );
			foreach ( var val in compareValues )
			{
				if ( this._compareFunction ( propertyValue, this.GetConvertedValue ( val , this.Element.CompareValueType ) ) )
				{
					return true;
				}
			}
			return false;
		}

		protected virtual bool _compareFunction ( object value1, object value2 )
		{
			return false;
		}
    }
}
